/*
** Copyright (C) 2010 Calin Radoni
**
** This file is part of CHScanner.
**
** CHScanner is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** CHScanner is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with CHScanner. If not, see <http://www.gnu.org/licenses/>.
*/

#include "StdAfx.h"
#include "MIGMPPacketList.h"

#include <algorithm>

//---------------------------------------------------------------------------

MIGMPPacketList::MIGMPPacketList(void)
{
}

MIGMPPacketList::~MIGMPPacketList(void)
{
	CleanUp();
}

//---------------------------------------------------------------------------

void MIGMPPacketList::CleanUp(void)
{
	MIGMPPacket *mpi;

	for(iter=theVector.begin(); iter!=theVector.end(); iter++){
		mpi = *iter;
		if(mpi!=NULL){
			*iter = NULL;
			delete mpi;
		}
	}
	theVector.clear();
}

//---------------------------------------------------------------------------

MIGMPPacket* MIGMPPacketList::CreatePackInfo(void)
{
	MIGMPPacket* mpi;

	try{
		mpi = new MIGMPPacket;
	}
	catch(...){
		mpi = NULL;
	}
	
	return mpi;
}

//---------------------------------------------------------------------------

MIGMPPacket* MIGMPPacketList::FindPackInfo(MIGMPPacket* mpiIn)
{
	MIGMPPacket* mpi;
	MIGMPPacket* res;
	DWORD a1, a2;

	if(mpiIn==NULL) return NULL;

	res = NULL;
	a2  = mpiIn->addr.GetD();
	for(iter=theVector.begin(); iter!=theVector.end() && res==NULL; iter++){
		mpi = *iter;
		if(mpi!=NULL){
			if(mpi->type==mpiIn->type){
				if(mpi->recordType==mpiIn->recordType){
					a1 = mpi->addr.GetD();
					if(a1==a2)
						res = mpi;
				}
			}
		}
	}

	return res;
}

//---------------------------------------------------------------------------

bool MIGMPPacketList::Add(MIGMPPacket* mpiIn)
{
	MIGMPPacket* mpi;
	int cnt;

	if(mpiIn==NULL) return true;	// nothing to add

	mpi = CreatePackInfo();
	if(mpi==NULL) return false;

	mpi->LoadFromPointer(mpiIn);

	cnt = (int)theVector.size();
	theVector.insert(theVector.begin(), mpi);
	cnt = (int)theVector.size() - cnt;
	if(cnt!=1){
		delete mpi;
		return false;
	}

	return true;
}

bool MIGMPPacketList::AddNoDuplicates(MIGMPPacket* mpiIn)
{
	MIGMPPacket* mpi;

	mpi = FindPackInfo(mpiIn);
	if(mpi!=NULL) return true;

	return Add(mpiIn);
}

void MIGMPPacketList::Clear(void)
{
	CleanUp();
}

//---------------------------------------------------------------------------

int MIGMPPacketList::GetSize(void)
{
	return (int)theVector.size();
}

MIGMPPacket* MIGMPPacketList::GetByIdx(int idxIn)
{
	if(idxIn<0)          return NULL;
	if(idxIn>=GetSize()) return NULL;

	return theVector[idxIn];
}

//---------------------------------------------------------------------------

bool MPackInfoGreater(MIGMPPacket* a1, MIGMPPacket* a2)
{
	DWORD addr1, addr2;

	if(a2==NULL) return true;
	if(a1==NULL) return false;

	if(a1->type!=a2->type)
		return a1->type < a2->type;

	if(a1->recordType!=a2->recordType)
		return a1->recordType < a2->recordType;
	
	addr1 = a1->addr.GetD();
	addr2 = a2->addr.GetD();
	return addr1 < addr2;
}

void MIGMPPacketList::SortTheList(void)
{
	std::sort(theVector.begin(), theVector.end(), MPackInfoGreater);
}

void MIGMPPacketList::RandomizeList(void)
{
	std::random_shuffle(theVector.begin(), theVector.end());
}

//---------------------------------------------------------------------------
